package cn.lianyutiantang.controller;


import cn.lianyutiantang.model.FileObj;
import cn.lianyutiantang.model.RealPathDTO;
import cn.lianyutiantang.model.Result;
import cn.lianyutiantang.model.ResultDTO;
import cn.lianyutiantang.model.zipCompress.FileBean;
import cn.lianyutiantang.model.zipCompress.ZipCompressBean;
import cn.lianyutiantang.service.user.FileService;
import cn.lianyutiantang.utils.*;
import com.alibaba.druid.util.HttpClientUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.ZipOutputStream;

/**
 * Created by lianyutiantang on 2018/8/16.
 * 图片上传
 */
@Controller
public class FileController {
    @Value("${windowsimg.path}")
    private String windowsimgPath; //保存到windos的路径
    @Value("${linuximg.path}")
    private String linuximgPath;//保存到Linux的路径
     @Value("${system.backupurl}")
    private String systemBackupUrl;//系backupurl统备份文件服务器url
    @Value("${system.sysremark}")
    private String systemSysremark;//主机保存之后留存的痕迹
    @Value("${system.backsysremark}")
    private String systemBackSysRemark;//备份机器文件



    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    @Autowired
    private FileService fileService;

    /**
     * tomcat目录 E:\svnImgService\source_code\file\target\file\
     * 请求URL格式 /upload?type=picture&directory=/mypic&size=128&same=true
     * 具体参数说明如下：
     * directory : 业务功能目录，建议必填,如上传用户头像,设置directory为head,则所有头像均保存在head文件夹下
     * type：限制上传文件类型,picture, word，excel，多种类型用逗号分开
     * size：图片缩放大小,默认128，若size=100则图片最大宽度"或"高度为100
     * same：是否等比缩放图片,默认为true，缩放大小根据参数size而定，如果为same=false则生成图片宽高均为size大小（原图为长方形则会变形）
     *
     * @throws IOException
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public void upload(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            if (!validFileType(request)) {
                out.println(JsonUtil.objectToJson(new Result(false, "上传失败,存在不允许上传的文件类型")));
                return;
            }
            out.println(JsonUtil.objectToJson(new Result(true, "上传成功", createFile(request))));
        } catch (MaxUploadSizeExceededException ex) {
            out.println(JsonUtil.objectToJson(new Result(false, "文件太大，请重新选择上传")));
        } catch (Exception ex) {
            logger.error("上传失败", ex);
            out.println(JsonUtil.objectToJson(new Result(false, "上传失败")));
        }
    }

    /**
     * 请求URL格式 /upload?type=picture&directory=/mypic&size=128&same=true
     * 具体参数说明如下：
     * directory : 业务功能目录，建议必填,如上传用户头像,设置directory为head,则所有头像均保存在head文件夹下
     * type：限制上传文件类型,picture, word，excel，多种类型用逗号分开
     * size：图片缩放大小,默认128，若size=100则图片最大宽度"或"高度为100
     * same：是否等比缩放图片,默认为true，缩放大小根据参数size而定，如果为same=false则生成图片宽高均为size大小（原图为长方形则会变形）
     *
     * @throws IOException
     */
    @RequestMapping(value = "/uploadFileAndChangeToPDf", method = RequestMethod.POST)
    public void uploadFileAndChangeToPDf(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        List<FileObj> fileObjs = null;
        try {
            if (!validFileType(request)) {
                out.println(JsonUtil.objectToJson(new Result(false, "上传失败,存在不允许上传的文件类型")));
                return;
            }
            fileObjs = createFile(request);
            if (fileObjs != null && fileObjs.size() > 0 && fileObjs.get(0).getId() != null) {
                final String pathTomcat = request.getSession().getServletContext().getRealPath("/");
                for (final FileObj obj : fileObjs) {
                    if (obj.getOrigPath() != null && !obj.getOrigPath().equals("")) {
                        String origPath = obj.getOrigPath().substring(1);
                        final String sourceFile = pathTomcat + origPath.replace("/", "\\");
//                        String pathAndsuffix[]=sourceFile.split("\\.");//其实就是想把doc改成pdf 注意点是特殊字符需要用转义符
//                        final String toFile=pathAndsuffix[0]+".pdf";
                        //根据长度取数组的最后一个元素
                        int i = sourceFile.lastIndexOf(".");
                        final String toFile = sourceFile.substring(0, i) + ".pdf";
                        //开启新的线程--异步执行方法
                        try {
                            ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
                            cachedThreadPool.execute(new Runnable() {
                                public void run() {
                                    Word2PdfUtil d = new Word2PdfUtil();
                                    //d.wordToPDF(sourceFile, toFile);//把doc转换成pdf
                                    d.wordToPDF1(sourceFile, toFile);//把doc转换成pdf
                                    FileObj fileObj = new FileObj();
                                    fileObj.setId(obj.getId());//设置文件主键


                                    int i = fileService.updateCallBackReport(fileObj);//转换完成之后回填存放这个文件的其他状态
                                }
                            });
                            cachedThreadPool.shutdown();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }

                out.println(JsonUtil.objectToJson(new Result(true, "调用成功，返回结果集见data", fileObjs)));
            } else {
                out.println(JsonUtil.objectToJson(new Result(false, "调用成功，但是并没有发现有文件", new ArrayList<FileObj>())));
            }

        } catch (MaxUploadSizeExceededException ex) {
            out.println(JsonUtil.objectToJson(new Result(false, "文件太大，请重新选择上传")));
        } catch (Exception ex) {
            logger.error("上传失败", ex);
            out.println(JsonUtil.objectToJson(new Result(false, "上传失败")));
        }
    }

    //转换为pdf
    @RequestMapping(value = "/changeToPDf", method = RequestMethod.POST)
    public void changeToPDf(MultipartHttpServletRequest request, HttpServletResponse response, @RequestBody FileObj fileObj) throws IOException {
        PrintWriter out = response.getWriter();
        String pathTomcat = request.getSession().getServletContext().getRealPath("/");
        if (fileObj.getOrigPath() != null && !fileObj.getOrigPath().equals("")) {
            Word2PdfUtil d = new Word2PdfUtil();
            String sourceFile = pathTomcat + fileObj.getOrigPath().replace("/", "\\");
            String pathAndsuffix[] = sourceFile.split("\\.");//其实就是想把doc改成pdf 注意点是特殊字符需要用转义符
            String toFile = pathAndsuffix[0] + ".pdf";
            d.wordToPDF1(sourceFile, toFile);//把doc转换成pdf
            out.println(JsonUtil.objectToJson(new Result(true, "转换pdf调用成功，返回结果集见data", fileObj)));
        } else {
            out.println(JsonUtil.objectToJson(new Result(false, "格式不正确", fileObj)));
        }

    }

    //获取获取图片的结果打成压缩包返回给前端
    @RequestMapping(value = "/downLoadZipFile", method = RequestMethod.GET)
    @ResponseBody
    public void downLoadZipFile(String workUploadFileIds, HttpServletRequest request, HttpServletResponse response) {
        logger.info("getBeautifulWorldFileZipObject:workUploadFileIds=" + workUploadFileIds);
        if (StringUtils.isEmpty(workUploadFileIds)) {
            logger.error("没有文件id不需要下载");
            return;
        }
        String ynWorkUploadFileIds[] = workUploadFileIds.split(",");
        List<FileObj> resultFiles = new ArrayList<FileObj>();//返回对象的个数
        //List<FileObj> files=   fileService.findByYnWorkUploadFileIds(ynWorkUploadFileIds);
        List<FileObj> files = fileService.findByYnWorkUploadFileIds(Arrays.asList(ynWorkUploadFileIds));
        if (files == null || files.size() == 0) {
            logger.error("数据查询不到传入文件id的数据！");
            return;
        }
        //压缩包部分代码
        Date currentTime = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String dateString = formatter.format(currentTime);
        String zipName = "";
        if (zipName != null && !zipName.equals("")) {
            zipName = zipName + ".zip";
        } else {
            zipName = dateString + ".zip";
        }
        response.setContentType("APPLICATION/OCTET-STREAM");
        try {
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(zipName, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        ZipOutputStream out = null;
        try {
            out = new ZipOutputStream(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            for (FileObj file : files) {
                RealPathDTO realPathDTO = new RealPathDTO();
                realPathDTO.setRealPath(file.getOrigPath());//入参文件物理路径
                ResultDTO result = RestTemplateUtil.getClient().postForObject("http://" + file.getInsideNetworkUrl() + "/getNetBase64ByRealPath", realPathDTO, ResultDTO.class);
                //File realFile = result.getData();
                logger.info("获取到的准备打包的图片base64字符串为："+result.getBase64().length());
                if (StringUtils.isEmpty(result.getBase64())) {
                    logger.info("获取不到服务器url"+"http://" + file.getInsideNetworkUrl() + "/getNetBase64ByRealPath"+JSON.toJSONString(realPathDTO));
                    logger.info("开始查询其备份服务器url"+"http://" + file.getInsideNetworkBackUrl() + "/getNetBase64ByRealPath"+JSON.toJSONString(realPathDTO));
                    result = RestTemplateUtil.postJson("http://" + file.getInsideNetworkBackUrl() + "/getNetBase64ByRealPath", realPathDTO, ResultDTO.class);
                }
                if (StringUtils.isNotEmpty(result.getBase64())) {
                    //先把base64 转成文件写进去然后再删除
                    String tempFilePath="";//文件路径
                    if (FileUtil.isOSLinux()) {
                        tempFilePath = this.linuximgPath+"tempFile/";
                    } else {
                        tempFilePath = this.windowsimgPath+"tempFile/";
                    }
                    String fileName =file.getWorkUploadFileId()+"."+file.getType();//文件名称加后缀
                    logger.info("tempFilePath:"+tempFilePath);
                    boolean isCreate=FileUtil.makePicture(result.getBase64(),tempFilePath,fileName);
                    //boolean isCreate=FileUtil.base64ToFile(result.getBase64(),tempFilePath,fileName);
                    logger.info("创建临时文件状态:"+isCreate);
                    if(isCreate){
                        File realFile =new File(tempFilePath+fileName);

                        logger.info("开始压缩打包当前文件:"+realFile.exists());
                        //这里应该考虑的是把文件那出来然后压缩打包回去
                        ZipUtils.doCompress(file.getName() + "." + file.getType(),realFile, out);
                        response.flushBuffer();
                        boolean deleteTempFileState=realFile.delete();
                        String serverIp = WebToolUtils.getLocalIP();
                        serverIp = serverIp + ":" + request.getLocalPort() + "";
                        logger.info("删除临时文件状态："+deleteTempFileState+",IP加端口："+serverIp+",文件临时路径："+tempFilePath);
                    }
                }else{
                    logger.info("--获取到的图片服务器的文件为null--");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        logger.error("getBeautifulWorldFileZipObject:文件打包成功");
    }

    //获取获取图片的结果转成base64回去
    @RequestMapping(value = "/getFilesFormatBase64", method = RequestMethod.POST)
    @ResponseBody
    public Result getFilesFormatBase64(@RequestBody RealPathDTO realPathDTO, HttpServletRequest request) {
        List<String> ynWorkUploadFileIds = new ArrayList<>();
        List<FileObj> fileList = realPathDTO.getFileList();
        if (realPathDTO == null || realPathDTO.getFileList() == null || realPathDTO.getFileList().size() == 0) {
            return new Result(false, "获取图片失败");
        } else {
            for (FileObj obj : fileList) {
                if (!StringUtils.isEmpty(obj.getWorkUploadFileId())) {
                    ynWorkUploadFileIds.add(obj.getWorkUploadFileId());
                }
            }
            if (fileList.size() == ynWorkUploadFileIds.size()) {
                //无操作
            } else {
                return new Result(false, "请确认你要返回的文件对象个数。");
            }
        }
        List<FileObj> resultFiles = new ArrayList<FileObj>();//返回对象的个数
        List<FileObj> files = fileService.findByYnWorkUploadFileIds(ynWorkUploadFileIds);
        for (FileObj file : files) {
            if (realPathDTO.getImgType().equals("origPath")) {//获取原文路径
                realPathDTO.setRealPath((file.getOrigPath()).replace("//", "/"));//入参文件物理路径
            } else if (realPathDTO.getImgType().equals("thumbPath")) {//获取缩略图路径
                realPathDTO.setRealPath((file.getThumbPath()).replace("//", "/"));//入参文件物理路径
            }else{
                realPathDTO.setRealPath((file.getOrigPath()).replace("//", "/"));//默认获取原文路径
            }
            ResultDTO result = RestTemplateUtil.postJson("http://" + file.getInsideNetworkUrl() + "/getNetBase64ByRealPath", realPathDTO, ResultDTO.class);
            String base64 = result.getBase64();
            if (base64 != null) {
                logger.info("获取到服务器url"+"http://" + file.getInsideNetworkUrl() + "/getNetBase64ByRealPath"+JSON.toJSONString(realPathDTO));
                file.setBase64(base64);
                for (FileObj f : fileList) {
                    if (file.getId().equals(f)) {
                        file.setParameter(f.getParameter());
                    }
                }
                resultFiles.add(file);
            }else{
                logger.info("获取不到服务器url"+"http://" + file.getInsideNetworkUrl() + "/getNetBase64ByRealPath"+JSON.toJSONString(realPathDTO));
                logger.info("开始查询其备份服务器url"+"http://" + file.getInsideNetworkBackUrl() + "/getNetBase64ByRealPath"+JSON.toJSONString(realPathDTO));
                result = RestTemplateUtil.postJson("http://" + file.getInsideNetworkBackUrl() + "/getNetBase64ByRealPath", realPathDTO, ResultDTO.class);
                base64 = result.getBase64();
                if(base64 != null){
                    file.setBase64(base64);
                    for (FileObj f : fileList) {
                        if (file.getId().equals(f)) {
                            file.setParameter(f.getParameter());
                        }
                    }
                    resultFiles.add(file);
                }else{
                    logger.info("所有服务器都没有找到该文件对象，请确认该文件对象的准确性"+JSON.toJSONString(realPathDTO));
                }
            }
        }
        return new Result(true, "获取图片成功", resultFiles);
    }

    /**
     * File 根据ip，端口，项目名称，获取图片的文件URL地址获得File文件并返回回来
     *
     * @param realPathDTO 图片实际file 对象
     * @return
     */
    @RequestMapping(value = "/getNetBase64ByRealPath", method = RequestMethod.POST)
    @ResponseBody
    public ResultDTO getNetBase64ByRealPath(@RequestBody RealPathDTO realPathDTO, HttpServletRequest request) {
        ResultDTO result  = new ResultDTO();
        result.setSuccess(true);
        try {
            logger.info("--有人来拿数据--" + WebToolUtils.getLocalIP() + ":" + request.getLocalPort() + "-->" + realPathDTO.getRealPath() + "");
            if (StringUtils.isEmpty(realPathDTO.getRealPath())) {
                result.setSuccess(false);
                result.setMsg("路径参数不能为空");
                return result;
            }
            File file = new File(realPathDTO.getRealPath());
            if (file.exists()) {
                result.setBase64(Base64Util.ImageToBase64ByLocal(realPathDTO.getRealPath()));
                result.setMsg("照片查找成功");
            } else {
                result.setSuccess(false);
                result.setMsg("照片查找失败");
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return result;
    }

    //创建文件【注意这里的图片上传有做图片+图片名称做md5校验的，如果图片和图片名称做md5校验一致的话就不用上传直接用回之前的图片】
    private List<FileObj> createFile(MultipartHttpServletRequest request) throws IOException {
        Date date = new Date();
        List<FileObj> returnFiles = new ArrayList<FileObj>();
        List<FileObj> saveFiles = new ArrayList<FileObj>();
        // String serverIp= FileUtil.getServerIp();
        String serverIp = WebToolUtils.getLocalIP();
        serverIp = serverIp + ":" + request.getLocalPort() + "";
        String insideNetworkDirectory = "";
        if (FileUtil.isOSLinux()) {
            insideNetworkDirectory = this.linuximgPath;
        } else {
            insideNetworkDirectory = this.windowsimgPath;
        }
        logger.info("--getServerIp()--" + serverIp);
        for (Iterator it = request.getFileNames(); it.hasNext(); ) {
            MultipartFile requestFile = request.getFile(String.valueOf(it.next()));
            String uploadFileName = requestFile.getOriginalFilename();//上传的文件名称。如：abc.jpg
            int index = uploadFileName.lastIndexOf(".");
            String name = uploadFileName.substring(0, index);//文件前缀名。如：abc
            String suffix = uploadFileName.substring(index);//文件后缀名。如：.jpg
            String suffixName = suffix.substring(1);//文件类型,如jpg,word
            String directory = getRelativePath(request.getParameter("directory"));//获得文件保存的相对路径,例/file/mypic/20171026
            //String saveDirectory = getIntAbsolutePath(directory, request);//创建目录 获取绝对路径 例D:\项目\source_code\file\mypic\20171026
            String saveDirectory = insideNetworkDirectory + directory;//创建目录 获取绝对路径 例D:\项目\source_code\file\mypic\20171026
            saveDirectory = saveDirectory.replace("//", "/");
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            String fileName = uuid + suffix;//保存的文件名称
            File file = new File(saveDirectory, fileName);
            FileUtils.copyInputStreamToFile(requestFile.getInputStream(), file);//生成文件
            String md5 = Md5FileUtil.md5(file) + Md5FileUtil.md5(uploadFileName);//获得文件的m5d值
            FileObj existObj = validExistFile(saveFiles, file, md5);
            if (existObj != null) {
                returnFiles.add(existObj);
                continue;
            }
            String smallName = "small" + fileName;
            if (suffix.toUpperCase().contains("MP4") || suffix.toUpperCase().contains("AVI")) {
                smallName = "small" + uuid + ".jpg";
            }

            if (isPicture(suffixName)) {//如果上传的文件是图片,则进行缩放
                FileUtil.zoomImage(file, new File(saveDirectory, smallName), suffixName, request);//创建缩略图
            } else if (suffix.toUpperCase().contains("MP4") || suffix.toUpperCase().contains("AVI")) {//如果是视频的话生成视频的缩略图
                //生成图片的路径
                String path1 = saveDirectory + "/" + smallName;
                //视频路径
                String videoPath = file.getAbsolutePath();
                VideoUtil.videosmallfile(videoPath, path1);
            }
            //组装结果
            FileObj entity = new FileObj();
            entity.setWorkUploadFileId(uuid);
            /*entity.setOrigPath(directory + "/" + fileName);
            entity.setThumbPath(directory + "/" + smallName);*/
            entity.setOrigPath(saveDirectory + "/" + fileName);
            entity.setThumbPath(saveDirectory + "/" + smallName);
            entity.setName(name);
            entity.setSize(requestFile.getSize());
            entity.setType(suffixName);
            entity.setCreateTime(date);
            entity.setStatus(1);
            entity.setMd5(md5);
            entity.setInsideNetworkUrl(serverIp);//新增图片服务器存放的局域网的url地址
            entity.setInsideNetworkDirectory(saveDirectory);//新增图片服务器存放的实体目录
            entity.setSysRemark(systemSysremark);
            entity.setBackSysRemark(systemBackSysRemark);
            entity.setInsideNetworkBackUrl(systemBackupUrl);
            saveFiles.add(entity);
            returnFiles.add(entity);
        }
        fileService.batchCreate(saveFiles);
        return returnFiles;
    }

    //通过md5验证文件是否已存在
    private FileObj validExistFile(List<FileObj> saveFiles, File file, String md5) {
        FileObj md5File = fileService.findByMd5(md5);//验证数据库是否存在此md5
        if (md5File != null) {
            file.delete();
            return md5File;
        }
        for (FileObj fileObj : saveFiles) {//验证当前上传的文件之间有没有重复
            if (md5.equals(fileObj.getMd5())) {
                file.delete();
                return fileObj;
            }
        }
        return null;
    }

    /**
     * app上传base64图片
     * @param request
     * @return
     */
    //   @RequestMapping("/appUpload", method = RequestMethod.POST)
    @RequestMapping(value = "/appUpload", method = RequestMethod.POST)
    @ResponseBody
    public Result appUpload(@RequestBody RealPathDTO realPathDTO, HttpServletRequest request) {
        List<FileObj> fileList=realPathDTO.getFileList();
        Date date = new Date();
        List<FileObj> resultFiles = new ArrayList<FileObj>();
        List<FileObj> saveFiles = new ArrayList<FileObj>();
        try {
            String serverIp = WebToolUtils.getLocalIP();
            serverIp = serverIp + ":" + request.getLocalPort() + "";
            String insideNetworkDirectory = "";
            if (FileUtil.isOSLinux()) {
                insideNetworkDirectory = this.linuximgPath;
            } else {
                insideNetworkDirectory = this.windowsimgPath;
            }
            logger.info("--getServerIp()--" + serverIp);
            String directory = getRelativePath("/app");//获得文件保存的相对路径

            for (FileObj fileObj : fileList) {
                if (fileObj.getBase64() == null) {
                    continue;
                }
                String saveDirectory = (insideNetworkDirectory + directory).replace("//", "/");
                saveDirectory= getIntAbsolutePath(saveDirectory, request);//创建目录

                String type = StringUtils.isBlank(fileObj.getType()) ? "jpg" : fileObj.getType();
                String uuid = UUID.randomUUID().toString().replaceAll("-", "");
                String fileName = uuid + "." + type;//保存的文件名称
                boolean ok =FileUtil.base64ToFile(fileObj.getBase64(), saveDirectory , fileName);
//                boolean ok = FileUtil.makePicture(fileObj.getBase64(), saveDirectory , fileName);//根据base64生成图片
                if (!ok) {
                    continue;
                }
                File file = new File(saveDirectory, fileName);
                String smallName = "small" + fileName;
                FileUtil.zoomImage(file, new File(saveDirectory, smallName), type, request);//创建缩略图
                //组装返回结果
                fileObj.setId(uuid);
                fileObj.setWorkUploadFileId(uuid);
                fileObj.setOrigPath(saveDirectory + "/" + fileName);
                fileObj.setThumbPath(saveDirectory + "/" + smallName);
                fileObj.setSize(file.length());
                fileObj.setCreateTime(date);
                fileObj.setType(type);
                fileObj.setStatus(1);
                // fileObj.setMd5(md5);
                if (StringUtils.isBlank(fileObj.getName())) {
                    fileObj.setName(datetimeFormater.get().format(date));
                }
                fileObj.setBase64("");//清空base64
                fileObj.setInsideNetworkUrl(serverIp);//新增图片服务器存放的局域网的url地址
                fileObj.setInsideNetworkDirectory(saveDirectory);//新增图片服务器存放的实体目录
                fileObj.setSysRemark(systemSysremark);
                fileObj.setBackSysRemark(systemBackSysRemark);
                fileObj.setInsideNetworkBackUrl(systemBackupUrl);
                saveFiles.add(fileObj);
                resultFiles.add(fileObj);
            }
            fileService.batchCreate(saveFiles);
            return new Result(true, "上传成功", resultFiles);
        } catch (IOException ex) {
            logger.error("上传失败", ex);
            return new Result(false, "上传失败");
        }
    }

    /**
     * app通过fileId获得base64图片
     * @param request
     * @return
     * @RequestMapping(value = "/appUpload", method = RequestMethod.POST)
     */
    @RequestMapping("/appDownload")
    @ResponseBody
    public Result appDownload(@RequestBody RealPathDTO realPathDTO , HttpServletRequest request) {
        List<FileObj> fileList=realPathDTO.getFileList();
        if (fileList == null || fileList.size() == 0) {
            return new Result(false, "获取图片失败");
        }
        List<FileObj> resultFiles = new ArrayList<FileObj>();
        List<String> ids =new ArrayList<>();
        for(FileObj obj:fileList){
            if(StringUtils.isNotEmpty(obj.getWorkUploadFileId())){
                ids.add(obj.getWorkUploadFileId());
            }
        }
        if(ids.size()==0){
            return new Result(false, "请输入需要获取图片的fileList中的workUploadFileId");
        }
        List<FileObj> files = fileService.findByYnWorkUploadFileIds(ids);
        for (FileObj file : files) {
            if (realPathDTO.getImgType().equals("origPath")) {//获取原文路径
                realPathDTO.setRealPath((file.getOrigPath()).replace("//", "/"));//入参文件物理路径
            } else if (realPathDTO.getImgType().equals("thumbPath")) {//获取缩略图路径
                realPathDTO.setRealPath((file.getThumbPath()).replace("//", "/"));//入参文件物理路径
            }else{
                realPathDTO.setRealPath((file.getOrigPath()).replace("//", "/"));//默认获取原文路径
            }
            ResultDTO result = RestTemplateUtil.postJson("http://" + file.getInsideNetworkUrl() + "/getNetBase64ByRealPath", realPathDTO, ResultDTO.class);
            String base64 = result.getBase64();
            if (base64 != null) {
                logger.info("获取到服务器url"+"http://" + file.getInsideNetworkUrl() + "/getNetBase64ByRealPath"+JSON.toJSONString(realPathDTO));
                file.setBase64(base64);
                for (FileObj f : fileList) {
                    if (file.getId().equals(f)) {
                        file.setParameter(f.getParameter());
                    }
                }
                resultFiles.add(file);
            }else{
                logger.info("获取不到服务器url"+"http://" + file.getInsideNetworkUrl() + "/getNetBase64ByRealPath"+JSON.toJSONString(realPathDTO));
                logger.info("开始查询其备份服务器url"+"http://" + file.getInsideNetworkBackUrl() + "/getNetBase64ByRealPath"+JSON.toJSONString(realPathDTO));
                result = RestTemplateUtil.postJson("http://" + file.getInsideNetworkBackUrl() + "/getNetBase64ByRealPath", realPathDTO, ResultDTO.class);
                base64 = result.getBase64();
                if(base64 != null){
                    file.setBase64(base64);
                    for (FileObj f : fileList) {
                        if (file.getId().equals(f)) {
                            file.setParameter(f.getParameter());
                        }
                    }
                    resultFiles.add(file);
                }else{
                    logger.info("所有服务器都没有找到该文件对象，请确认该文件对象的准确性"+JSON.toJSONString(realPathDTO));
                }
            }
        }
        return new Result(true, "获取图片成功", resultFiles);
    }

    /**
     * 单个文件下载文件
     *
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/download")
    public ModelAndView download(HttpServletRequest request, HttpServletResponse response, FileObj fileObj) {
        try {
            List<String> ids =new ArrayList<>();
            if(StringUtils.isNotEmpty(fileObj.getWorkUploadFileId())){
                ids.add(fileObj.getWorkUploadFileId());
            }
            if(ids.size()==0){
                logger.error("入参workUploadFileId不能为空");
                return null;
            }
            List<FileObj> files = fileService.findByYnWorkUploadFileIds(ids);
            if(files==null||files.size()==0){
                logger.error("根据workUploadFileId并没有获得文件对象");
                return null;
            }
            FileObj file=files.get(0);
            response.setContentType("text/html;charset=UTF-8");
            request.setCharacterEncoding("UTF-8");
            BufferedInputStream bis = null;
            BufferedOutputStream bos = null;
            RealPathDTO realPathDTO=new RealPathDTO();
            realPathDTO.setRealPath((file.getOrigPath()).replace("//", "/"));//默认获取原文路径
            ResultDTO result = RestTemplateUtil.postJson("http://" + file.getInsideNetworkUrl() + "/getNetBase64ByRealPath", realPathDTO, ResultDTO.class);
            logger.info("获取到的准备打包的图片base64字符串长度为："+result.getBase64().length());
            if (StringUtils.isEmpty(result.getBase64())) {
                logger.info("获取不到服务器url"+"http://" + file.getInsideNetworkUrl() + "/getNetBase64ByRealPath"+JSON.toJSONString(realPathDTO));
                logger.info("开始查询其备份服务器url"+"http://" + file.getInsideNetworkBackUrl() + "/getNetBase64ByRealPath"+JSON.toJSONString(realPathDTO));
                result = RestTemplateUtil.postJson("http://" + file.getInsideNetworkBackUrl() + "/getNetBase64ByRealPath", realPathDTO, ResultDTO.class);
            }
            if (StringUtils.isNotEmpty(result.getBase64())) {
                //先把base64 转成文件写进去然后再删除
                String tempFilePath="";//文件路径
                if (FileUtil.isOSLinux()) {
                    tempFilePath = this.linuximgPath+"tempFile/";
                } else {
                    tempFilePath = this.windowsimgPath+"tempFile/";
                }
                String fileName =file.getWorkUploadFileId()+"."+file.getType();//文件名称加后缀
                logger.info("tempFilePath:"+tempFilePath);
                boolean isCreate=FileUtil.makePicture(result.getBase64(),tempFilePath,fileName);
                //boolean isCreate=FileUtil.base64ToFile(result.getBase64(),tempFilePath,fileName);
                logger.info("创建临时文件状态:"+isCreate);
                if(isCreate){
                    File realFile =new File(tempFilePath+fileName);
                    logger.info("文件流输出文件:"+realFile.exists());
                    String downLoadPath = tempFilePath+fileName;
                    long fileLength = new File(downLoadPath).length();
                    response.setContentType("application/octet-stream");
                    response.setHeader("Content-disposition", "attachment; filename=" + fileName);
                    response.setHeader("Content-Length", String.valueOf(fileLength));
                    bis = new BufferedInputStream(new FileInputStream(downLoadPath));
                    bos = new BufferedOutputStream(response.getOutputStream());
                    byte[] buff = new byte[2048];
                    int bytesRead;
                    while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                        bos.write(buff, 0, bytesRead);
                    }
                    bis.close();
                    bos.close();
                    boolean deleteTempFileState=realFile.delete();
                    logger.info("--临时文件--"+tempFilePath+fileName+"--成功删除--");
                }
            }else{
                logger.info("所有服务器都没有找到该文件对象，请确认该文件对象的准确性"+JSON.toJSONString(realPathDTO));
            }
        } catch (Exception e) {
            e.printStackTrace();
            ModelAndView model = new ModelAndView("error/exception");
            model.addObject("exception", e);
            return model;
        }
        return null;
    }

    //判断上传文件是否为图片
    public boolean isPicture(String suffixName) {
        List<String> allowList = TYPES.get("picture");
        for (int i = 0, len = allowList.size(); i < len; i++) {
            if (suffixName.equalsIgnoreCase(allowList.get(i))) {
                return true;
            }
        }
        return false;
    }

    //获得文件保存的相对路径
    private String getRelativePath(String paramDirectory) {
        String directory = UPLOADFILES;
        if (StringUtils.isNotBlank(paramDirectory)) {
            directory = paramDirectory.startsWith("/") ? directory + paramDirectory : directory + "/" + paramDirectory;
        }
        return directory.endsWith("/") ? directory + dateFormater.get().format(new Date()) : directory + "/" + dateFormater.get().format(new Date());
    }

    //通过相对路径获得文件保存的相对路径,路径不存在则创建路径 上传图片
    private String getIntAbsolutePath(String directory, HttpServletRequest request) {
        File file = new File(directory);
        if (!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
        return directory;
    }

    //验证文件类型
    private boolean validFileType(MultipartHttpServletRequest request) {
        String paramType = request.getParameter("type");//限制的文件类型
        if (StringUtils.isBlank(paramType)) {
            return true;
        }
        boolean valid = true;
        for (Iterator it = request.getFileNames(); it.hasNext(); ) {
            MultipartFile requestFile = request.getFile(String.valueOf(it.next()));
            String uploadFileName = requestFile.getOriginalFilename();//上传的文件名称。如：abc.jpg
            if (!validFileType(paramType, uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1))) {//验证文件类型是否匹配限制的类型
                valid = false;
                break;
            }
        }
        return valid;
    }

    //验证是否允许上传请求类型
    private boolean validFileType(String paramType, String suffixName) {
        if (StringUtils.isBlank(paramType)) paramType = "picture";
        List<String> typeList = Arrays.asList(paramType.split(","));
        for (int i = 0, len = typeList.size(); i < len; i++) {
            String type = typeList.get(i);
            List<String> allowList = TYPES.get(type);
            if (allowList == null || allowList.size() == 0) return false;
            for (int j = 0, jlen = allowList.size(); j < jlen; j++) {
                if (suffixName.equalsIgnoreCase(allowList.get(j))) {
                    return true;
                }
            }
        }
        return false;
    }


    private static final String UPLOADFILES = "/file";
    private static final Map<String, List<String>> TYPES = new HashMap<String, List<String>>();

    public FileController() {
        List<String> PICTURE = new ArrayList<String>(), WORD = new ArrayList<String>(), EXCEL = new ArrayList<String>();
        PICTURE.add("JPG");//图片
        PICTURE.add("JPEG");//图片
        PICTURE.add("PJPEG");//图片
        PICTURE.add("GIF");//图片
        PICTURE.add("BMP");//图片
        PICTURE.add("PNG");//图片
        WORD.add("DOCX");//word
        WORD.add("DOC");//word
        EXCEL.add("XLSX");//excel
        EXCEL.add("XLS");//excel
        TYPES.put("picture", PICTURE);
        TYPES.put("word", WORD);
        TYPES.put("excel", EXCEL);
    }

    private final static ThreadLocal<SimpleDateFormat> dateFormater = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyyMMdd", Locale.SIMPLIFIED_CHINESE);
        }
    };

    private final static ThreadLocal<SimpleDateFormat> datetimeFormater = new ThreadLocal<SimpleDateFormat>() {
        @Override
        protected SimpleDateFormat initialValue() {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.SIMPLIFIED_CHINESE);
        }
    };

    //测试毁掉
    @ResponseBody
    @RequestMapping(value = "/testUpdateCallBackReport")
    public Result testUpdateCallBackReport(HttpServletRequest request, FileObj fileObj) {
        int i = fileService.updateCallBackReport(fileObj);
        Result result = new Result(true);
        result.setData(i);
        return result;
    }

}